package com.itheima.mp.utils;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.dto.PageDTO;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * PageDto 转换工具类，用于将分页查询结果转换为框架特定的分页对象。
 *
 * @author ChenPi
 * @since 2024/12/21 14:14
 */
public class PageDtoConvertUtil {
    /**
     * 针对MyBatis-Plus分页结果转换的工具类
     */
    public static class MyBatisPlus {

        /**
         * 返回空分页结果
         *
         * @param p   MybatisPlus的分页结果
         * @param <V> 目标VO类型
         * @param <P> 原始PO类型
         * @return VO的分页对象
         */
        public static <V, P> PageDTO<V> empty(Page<P> p) {
            return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList());
        }

        /**
         * 将MybatisPlus分页结果转为 VO分页结果
         *
         * @param p       MybatisPlus的分页结果
         * @param voClass 目标VO类型的字节码
         * @param <V>     目标VO类型
         * @param <P>     原始PO类型
         * @return VO的分页对象
         */
        public static <V, P> PageDTO<V> convertToVOPage(Page<P> p, Class<V> voClass) {
            // 1.非空校验
            List<P> records = p.getRecords();
            if (records == null || records.isEmpty()) {
                // 无数据，返回空结果
                return empty(p);
            }
            // 2.数据转换
            List<V> vos = BeanUtil.copyToList(records, voClass);
            // 3.封装返回
            return new PageDTO<>(p.getTotal(), p.getPages(), vos);
        }

        /**
         * 将MybatisPlus分页结果转为 VO分页结果，允许用户自定义PO到VO的转换方式
         *
         * @param p         MybatisPlus的分页结果
         * @param convertor PO到VO的转换函数
         * @param <V>       目标VO类型
         * @param <P>       原始PO类型
         * @return VO的分页对象
         */
        public static <V, P> PageDTO<V> convertToVOPage(Page<P> p, Function<P, V> convertor) {
            // 1.非空校验
            List<P> records = p.getRecords();
            if (records == null || records.isEmpty()) {
                // 无数据，返回空结果
                return empty(p);
            }
            // 2.数据转换
            List<V> vos = records.stream().map(convertor).collect(Collectors.toList());
            // 3.封装返回
            return new PageDTO<>(p.getTotal(), p.getPages(), vos);
        }
    }

    // 如果将来需要支持其他框架的分页转换，可以在这里添加类似的内部类
}
